// This source is subject to the Microsoft Public License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Resources;
using System.Threading;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace QuoteAdvantage
{
   /// <summary>
   /// Configurator screen for adding child products to a parent item
   /// </summary>
   public class CustomizeItem : System.Web.UI.Page
   {      
      protected Engine         eng = null;
      protected Quote          objQuote = null;
      protected QuoteDetail    objParentItem = null;
      protected Guid           guidQuoteDetailId;
      protected Guid           guidQuoteId;
      protected Organization   objOrganization = null;
      protected string strRootCategoryId = "";
      protected bool           m_bItemsSelected = false;   // Has nothing been selected at all?
      protected const string   m_strEmptySelection = "_EMPTY_SELECTION_";
      protected string m_bShowValidationWarning;  // Flag to display Javascript warning
      protected string m_strCloseUrl = "";
      protected string strDiscountPriceLabel;
      protected string strListPriceLabel;
      protected string strValidationProblems;
      protected string strCurrencySymbol;
      protected int nCurrencyFormatCode;
      protected ResourceManager m_mgrResource;
      protected XmlNode nodeCategoryRoot;

      protected System.Web.UI.WebControls.Panel pnlControlList;
      protected System.Web.UI.WebControls.Label lblConfigWarning;
      protected System.Web.UI.WebControls.LinkButton lnkClose;
      protected System.Web.UI.WebControls.Label lblProductName;
      protected System.Web.UI.WebControls.Label lblPrice;
      protected System.Web.UI.WebControls.Button btnCustomize;
      protected System.Web.UI.WebControls.TextBox txtCustomizeData;
      protected System.Web.UI.WebControls.LinkButton lnkUpdatePrice;

      private void Page_Load(object sender, System.EventArgs e)
      {
         m_bShowValidationWarning = "false"; 

         // Set the culture and UI culture to the browser's accept language
         Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
         Thread.CurrentThread.CurrentUICulture = new CultureInfo(Request.UserLanguages[0]);

         m_mgrResource = new ResourceManager("QuoteAdvantage.strings", typeof(CustomizeQuote).Assembly);
         eng = new Engine(this.Trace, m_mgrResource);
         guidQuoteId = new Guid(Request.QueryString["QuoteId"]);
         guidQuoteDetailId = new Guid(Request.QueryString["QuoteDetailId"]);
         objQuote = eng.LoadQuote(guidQuoteId);
         objParentItem = objQuote.FindQuoteDetail(guidQuoteDetailId);  
         
         if (Request.QueryString["CategoryId"] != null)
         {
            strRootCategoryId = Request.QueryString["CategoryId"];
         }

         nodeCategoryRoot = eng.LoadCategoryList(objParentItem);   
         
         if (nodeCategoryRoot == null)
         {
            Response.Redirect("NoCustomization.aspx?QuoteId=" + Request.QueryString["QuoteId"]);
         }
         else
         {
            LoadResources();
            BuildControlList(nodeCategoryRoot);
            lblConfigWarning.Visible = false;

            if (objParentItem.ConfigParentId == Guid.Empty)
            {
               lblProductName.Text = "Child Products for: " + objParentItem.Name;
            }
            else
            {
               lblProductName.Text = "Nested Child Product: " + objParentItem.Name;
            }

            if (!this.IsPostBack)
            {
               SetControlValues();

               if (objQuote.IsReadOnly)
               {
                  UpdateReadOnlyPrice();
               }
               else
               {
                  UpdatePrice();
               }

               txtCustomizeData.Style.Add("visibility", "hidden");
               btnCustomize.Style.Add("visibility", "hidden");
            }
         }
      }

      #region Web Form Designer generated code
      override protected void OnInit(EventArgs e)
      {
         //
         // CODEGEN: This call is required by the ASP.NET Web Form Designer.
         //
         InitializeComponent();
         base.OnInit(e);
      }
      
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {    
         this.lnkUpdatePrice.Click += new System.EventHandler(this.lnkUpdatePrice_Click);
         this.lnkClose.Click += new System.EventHandler(this.lnkClose_Click);
         this.btnCustomize.Click += new System.EventHandler(this.btnCustomize_Click);
         this.Load += new System.EventHandler(this.Page_Load);

      }
      #endregion

      private void LoadResources() 
      {                                               
         lnkUpdatePrice.Text = m_mgrResource.GetString("cmdUpdatePrice");
         lnkClose.Text = m_mgrResource.GetString("cmdClose"); 
         lblConfigWarning.Text = m_mgrResource.GetString("lblConfigWarning");
         lblProductName.Text = m_mgrResource.GetString("lblProductName");
         strDiscountPriceLabel = m_mgrResource.GetString("lblDiscountPrice");
         strListPriceLabel = m_mgrResource.GetString("lblListPrice"); 

         objOrganization = eng.LoadOrganization();
         strCurrencySymbol = objOrganization.CurrencySymbol;
         nCurrencyFormatCode = objOrganization.CurrencyFormatCode;
      }

      private void BuildControlList(XmlNode nodeRoot)
      {
         int   nYPos = 28;
         
         foreach (XmlNode nodeCategory in nodeRoot.ChildNodes)
         {
            if (nodeCategory.NodeType == XmlNodeType.Element)
            {
               Label    lblCategoryName = new Label();
               string   strCategoryId = nodeCategory.Attributes["categoryId"].Value;
               string   strCategoryType = "SingleSelect";

               if (nodeCategory.Attributes["type"] != null)
               {
                  strCategoryType = nodeCategory.Attributes["type"].Value;
               }

               if (strCategoryId == "")
               {
                  throw new ApplicationException("Invalid category ID value for the category named: " + nodeCategory.Attributes["name"].Value);
               }  

               lblCategoryName.Text = "&nbsp;" + nodeCategory.Attributes["name"].Value; 
               lblCategoryName.ID = "lbl" + nodeCategory.Attributes["categoryId"].Value;
               lblCategoryName.CssClass = "LabelCategory";
               lblCategoryName.Style.Add("position", "absolute");             
               lblCategoryName.Style.Add("left", "20px");
               lblCategoryName.Style.Add("top", nYPos.ToString() + "px");
               lblCategoryName.Style.Add("width", "570px");
               lblCategoryName.Style.Add("height", "20px");   
               pnlControlList.Controls.Add(lblCategoryName);

               nYPos += 24;
               
               Label    lblConfigErrorMessage = new Label();

               lblConfigErrorMessage.ID = "ConfigErrorMessage_" + strCategoryId;
               lblConfigErrorMessage.Text = "";
               lblConfigErrorMessage.CssClass = "LabelError";
               // error message and radio button list will overlap until the error is displayed
               lblConfigErrorMessage.Style.Add("position", "absolute");
               lblConfigErrorMessage.Style.Add("left", "20px");
               lblConfigErrorMessage.Style.Add("top", nYPos.ToString() + "px");
               lblConfigErrorMessage.Style.Add("width", "560px");
               lblConfigErrorMessage.Visible = false;
               pnlControlList.Controls.Add(lblConfigErrorMessage); 

               if (strCategoryType == "SingleSelect")
               {
                  // Build a multi-selection category with radio buttons
                  RadioButtonList radioList = BuildRadioButtonList(strCategoryId, nodeCategory, nYPos);
                  nYPos += radioList.Items.Count * 21; // Space for each item
                  nYPos += 45; // blank space between categories   
                  pnlControlList.Controls.Add(radioList);
               }
               else
               {
                  // Build a multi-selection category with checkboxes
                  CheckBoxList checkList = BuildCheckBoxList(strCategoryId, nodeCategory, nYPos);
                  nYPos += checkList.Items.Count * 21; // Space for each item
                  nYPos += 45; // blank space between categories   
                  pnlControlList.Controls.Add(checkList);
               }
            }
         } // end foreach

         nYPos += 28;
         Label    lblBlankSpace = new Label();

         lblBlankSpace.ID = "lblBlank";
         lblBlankSpace.Text = "";
         lblBlankSpace.Visible = true;
         lblBlankSpace.CssClass = "Label";
         lblBlankSpace.Style.Add("position", "absolute");
         lblBlankSpace.Style.Add("left", "20px");
         lblBlankSpace.Style.Add("top", nYPos.ToString() + "px");
         lblBlankSpace.Style.Add("width", "550px");
         pnlControlList.Controls.Add(lblBlankSpace); 
      }

      private RadioButtonList BuildRadioButtonList(string strCategoryId, XmlNode nodeCategory, int nYPos)
      {
         RadioButtonList   radioList = new RadioButtonList(); 
         radioList.ID = "categoryList" + strCategoryId;
         radioList.DataSource = strCategoryId;
         radioList.CssClass = "Label";
         radioList.Style.Add("position", "absolute");
         radioList.Style.Add("left", "40px");
         radioList.Style.Add("top", nYPos.ToString() + "px");

         foreach (XmlNode nodeItem in nodeCategory.ChildNodes)
         {
            if (nodeItem.NodeType == XmlNodeType.Element)
            {
               string strProductNumber = "";                 
               string strProductText = "";
               string strRuleFileName = "";
                              
               if (nodeItem.Attributes["ruleFileName"] != null)
               {
                  strRuleFileName = nodeItem.Attributes["ruleFileName"].Value;
               }
           
               if (nodeItem.Name == "EmptyItem")
               {
                  // Empty choice
                  strProductNumber = m_strEmptySelection;
                  strProductText = nodeItem.InnerText;
               }
               else if (nodeItem.Name == "Item")
               {
                  // Regular item
                  try
                  {
                     strProductNumber = nodeItem.Attributes["productId"].Value.ToUpper();                 
                  }
                  catch (Exception)
                  {
                     throw new ApplicationException("Error processing rules XML file. 'productId' attribute was not found.");
                  }

                  strProductText = GetPriceText(strProductNumber, strCategoryId);
                  
                  if (strRuleFileName != "")
                  {
                     strProductText += @"&nbsp;&nbsp;<a href=""#"" onclick=""return onCustomizeItem('" + strCategoryId +@"', '" + strProductNumber + @"', " + radioList.Items.Count + @")"">Customize</a>";
                  }

               }

               radioList.Items.Add(new ListItem(strProductText, strProductNumber));
            }
         }
         
         return radioList;
      }

      private CheckBoxList BuildCheckBoxList(string strCategoryId, XmlNode nodeCategory, int nYPos)
      {
         CheckBoxList   checkList = new CheckBoxList(); 
         checkList.ID = "categoryList" + strCategoryId;
         checkList.DataSource = strCategoryId;
         checkList.CssClass = "Label";
         checkList.Style.Add("position", "absolute");
         checkList.Style.Add("left", "40px");
         checkList.Style.Add("top", nYPos.ToString() + "px");

         foreach (XmlNode nodeItem in nodeCategory.ChildNodes)
         {
            if (nodeItem.NodeType == XmlNodeType.Element)
            {
               string strProductNumber = "";                 
               string strProductText = "";
               string strRuleFileName = "";
                              
               if (nodeItem.Attributes["ruleFileName"] != null)
               {
                  strRuleFileName = nodeItem.Attributes["ruleFileName"].Value;
               }

               if (nodeItem.Name == "EmptyItem")
               {
                  // Empty choice
                  strProductNumber = m_strEmptySelection;
                  strProductText = nodeItem.InnerText;
               }
               else if (nodeItem.Name == "Item")
               {
                  // Regular item
                  try
                  {
                     strProductNumber = nodeItem.Attributes["productId"].Value.ToUpper();                 
                  }
                  catch (Exception)
                  {
                     throw new ApplicationException("Error processing rules XML file. 'productId' attribute was not found.");
                  }

                  strProductText = GetPriceText(strProductNumber, strCategoryId);
                  
                  if (strRuleFileName != "")
                  {
                     strProductText += @"&nbsp;&nbsp;<a href=""#"" onclick=""return onCustomizeItem('" + strCategoryId +@"', '" + strProductNumber + @"', " + checkList.Items.Count + @")"">Customize</a>";
                  }
               }

               checkList.Items.Add(new ListItem(strProductText, strProductNumber));
            }
         }
         
         return checkList;
      }

      private string GetPriceText(string strProductNumber, string strCategoryId)
      {
         string      strProductText = "";
         string      strPrice = ""; 

         Product     objProduct = eng.LoadProductFromProductNumber(strProductNumber, objQuote.PriceLevelId);
         objProduct.CategoryId = strCategoryId;

         if (objProduct != null)
         {
            eng.ApplyUnitOfMeasure(nodeCategoryRoot, objProduct, objOrganization);
            string strUnitOfMeasure = eng.LoadUnitOfMeasure(objProduct.UnitOfMeasureId, objOrganization);

            QuoteDetail objLineItem = objQuote.FindCategoryItem(objParentItem, strCategoryId, strProductNumber);
            strProductText = objProduct.Name;             

            if (objLineItem != null)
            {
               strPrice = strCurrencySymbol + objLineItem.PricePerUnit.ToString();    
            }
            else
            {
               // This item hasn't been added yet. Use either the product price or the product list price
               if (objProduct.Price > Convert.ToDecimal(0.01))
               {
                  strPrice = Product.FormatCurrency(objProduct.Price, nCurrencyFormatCode, strCurrencySymbol);
               }
               else
               {
                  strPrice = Product.FormatCurrency(objProduct.ListPrice, nCurrencyFormatCode, strCurrencySymbol);
               }
            }

            strProductText += " [" + strPrice + " - " + strUnitOfMeasure + "]";  

            if (objProduct.ProductUrl != null)
               strProductText += @"&nbsp;&nbsp;<a target=""_blank"" href=""" + objProduct.ProductUrl + @"""><img border=""0"" src=""Help.gif""/></a>";
         }
         else
         {
            throw new ApplicationException("The item with Product ID  = " + strProductNumber + " could not be loaded.");
         }

         return strProductText;
      }

      private void SetControlValues()
      {
         foreach (Control ctl in pnlControlList.Controls)
         {
            if (ctl is RadioButtonList)
            {
               SetRadioButtonValues((RadioButtonList)ctl);
            }
            else if (ctl is CheckBoxList)
            {
               SetCheckBoxValues((CheckBoxList)ctl);
            }
         } //end foreach

         if (m_bItemsSelected)
         {
            ValidateConfiguration();
         }
         else
         {
            lblConfigWarning.Visible = true;
            lblConfigWarning.Text = m_mgrResource.GetString("msgPleaseSelect");
         }
      }   
      
      private void SetRadioButtonValues(RadioButtonList radioList)
      {
         string strCategoryId = radioList.DataSource.ToString(); 
               
         QuoteDetail  objCategoryItem = objQuote.FindCategoryItem(objParentItem, strCategoryId);

         if (objCategoryItem == null)
         {
            try
            {
               // By default, select an empty item if nothing else was chosen.
               radioList.SelectedValue = m_strEmptySelection;  
            }
            catch(Exception)
            {
               // Ignore error if an empty item isn't available
            }
         }
         else
         {
            try
            {
               radioList.SelectedValue = objCategoryItem.ProductNumber.ToUpper();   
               m_bItemsSelected = true;
            }
            catch (Exception)
            {
               // There's a chance that the rule file was modified and the target item was removed.
            }
         }                
      }      
      
      private void SetCheckBoxValues(CheckBoxList checkList)
      {
         foreach (ListItem objItem in checkList.Items)
         {
            string strCategoryId = checkList.DataSource.ToString(); 
            string strPartNumber = objItem.Value;

            QuoteDetail  objCategoryItem = objQuote.FindCategoryItem(objParentItem, strCategoryId, strPartNumber);

            if (objCategoryItem == null)
            {
               objItem.Selected = false;
            }
            else
            {
               objItem.Selected = true;
            }  
         }  // end foreach

         RefreshEmptyItemCheckboxes(checkList);
      }         
 

      // If a multiselect category has no selections, then automatically activate any EmptyItem entries
      private void RefreshEmptyItemCheckboxes(CheckBoxList checkList)
      {
         bool bItemSelected = false;

         foreach (ListItem objItem in checkList.Items)
         {
            if (objItem.Selected && objItem.Value != m_strEmptySelection)
            {
               bItemSelected = true;
            }  
         }  

         // If nothing was selected, then activate any EmptyItem entries
         // If something was selected, then turn off the EmptyItems
         foreach (ListItem objItem in checkList.Items)
         {
            if (objItem.Value == m_strEmptySelection)
            {
               objItem.Selected = !bItemSelected;
            }
         }
      }

      private bool ValidateConfiguration()
      {
         bool  bResult = true;

         try
         {
            // Hide all error messages
            foreach (Control ctl in pnlControlList.Controls)
            {
               if (ctl.ID != null)
               {
                  if (ctl.ID.IndexOf("ConfigErrorMessage_") != -1)
                  {
                     Label ctlLabel = (Label)ctl;
                     ctl.Visible = false;  

                     // Make sure the radiobutton list is positioned correctly
                     string strCategoryId = ctl.ID.Replace("ConfigErrorMessage_", "");
                     WebControl    ctlList = (WebControl)pnlControlList.FindControl("categoryList" + strCategoryId);
                     ctlList.Style["top"] = ctlLabel.Style["top"];
                  }                  
               }
            }

            eng.ValidateQuoteDetail(objParentItem);
         }
         catch (ProductConfigException ex)
         {
            lblConfigWarning.Visible = true;
            lblConfigWarning.Text = m_mgrResource.GetString("lblConfigWarning");
            
            Label lblErrorMessage = (Label)pnlControlList.FindControl("ConfigErrorMessage_" + ex.CategoryId);
            lblErrorMessage.Visible = true;
            lblErrorMessage.Text = ex.Message;

            WebControl   radioList = (WebControl)pnlControlList.FindControl("categoryList" + ex.CategoryId);
            
            string   strTop = radioList.Style["top"].ToString();  
            strTop = strTop.Replace("px", "");
            int nValue = Convert.ToInt32(strTop.Replace("px", ""));
            radioList.Style["top"] = Unit.Pixel(nValue + 34).ToString();
            bResult = false;
         }
      
         return bResult;
      }

      private void lnkUpdatePrice_Click(object sender, System.EventArgs e)
      {
         if (objQuote.IsReadOnly)
         {
            string strUrl = "CustomizeItem.aspx?QuoteId=" + objQuote.QuoteId + "&QuoteDetailId=" + objParentItem.QuoteDetailId;
            Response.Redirect(strUrl);
         }
         else
         {
            UpdatePrice();
            ValidateConfiguration();
         }
      }

      private void UpdatePrice()
      {
         ArrayList   objSelectedItemList = new ArrayList(10);

         foreach (Control ctl in pnlControlList.Controls)
         {
            if (ctl is RadioButtonList)
            {
               // This is a single select category
               RadioButtonList   radioList = (RadioButtonList)ctl;
               string strCategoryId = radioList.DataSource.ToString(); 
               string strProductNumber = radioList.SelectedValue;

               if (strProductNumber == m_strEmptySelection)
               {
                  // The No Choice item was selected
                  Product objProduct = new Product();
                  objProduct.ProductNumber = "";
                  objProduct.CategoryId = strCategoryId;                   
                  objSelectedItemList.Add(objProduct);
               }
               else if (strProductNumber != "")                      
               {
                  // A regular item was selected
                  //Product objProduct = eng.LoadProductFromProductNumber(strProductNumber, objQuote.PriceLevelId);
                  //objProduct.CategoryId = strCategoryId;  
                  Product objProduct = LoadProduct(strProductNumber, strCategoryId);

                 //eng.ApplyUnitOfMeasure(nodeCategoryRoot, objProduct, objOrganization);
                  objSelectedItemList.Add(objProduct);
               }
            }
            else if (ctl is CheckBoxList)
            {
               // This is a multi-select category
               CheckBoxList   checkList = (CheckBoxList)ctl;
               string strCategoryId = checkList.DataSource.ToString(); 
               
               foreach (ListItem objItem in checkList.Items)
               {
                  if (objItem.Selected)
                  {
                     string strProductNumber = objItem.Value;

                     if (strProductNumber == m_strEmptySelection)
                     {
                        // The No Choice item was selected
                        Product objProduct = new Product();
                        objProduct.ProductNumber = "";
                        objProduct.CategoryId = strCategoryId;                   
                        objSelectedItemList.Add(objProduct);
                     }
                     else if (strProductNumber != "")                      
                     {
                        // A regular item was selected
                        //Product objProduct = eng.LoadProductFromProductNumber(strProductNumber, objQuote.PriceLevelId);
                        //objProduct.CategoryId = strCategoryId;  
                        //eng.ApplyUnitOfMeasure(nodeCategoryRoot, objProduct, objOrganization);
                        Product objProduct = LoadProduct(strProductNumber, strCategoryId);

                        objSelectedItemList.Add(objProduct);
                     }
                  }
               }

               RefreshEmptyItemCheckboxes(checkList);
            }
         } //end foreach

         decimal nPercentDiscount = objParentItem.ConvertFixedDiscountToPercentage();

         eng.UpdateLineItems(objQuote, objParentItem, objSelectedItemList, objOrganization);        
                                 
         // Recalculate the percentage discount
         objParentItem.ApplyPercentageMultiplier(nPercentDiscount);
         eng.UpdateQuoteDetail(objParentItem);

         decimal nPrice = objParentItem.CalculatePrice();

         if (objParentItem.Quantity > 1)
         {
            nPrice = nPrice / objParentItem.Quantity;;
         }                      
         
         lblPrice.Text = Product.FormatCurrency(nPrice, nCurrencyFormatCode, strCurrencySymbol);
      }

      private Product LoadProduct(string strProductNumber, string strCategoryId)
      {
         Product objProduct = eng.LoadProductFromProductNumber(strProductNumber, objQuote.PriceLevelId);
         objProduct.CategoryId = strCategoryId;  

         XmlNode nodeProduct = eng.GetProductNode(nodeCategoryRoot, strCategoryId, objProduct.ProductNumber);
         
         if (nodeProduct.Attributes["allowDiscounting"] != null)
         {
            objProduct.AllowDiscounting = Convert.ToBoolean(nodeProduct.Attributes["allowDiscounting"].Value);
         }  

         eng.ApplyUnitOfMeasure(nodeCategoryRoot, objProduct, objOrganization);

         return objProduct;
      }           

      private void UpdateReadOnlyPrice()
      {
         decimal nPercentDiscount = objParentItem.ConvertFixedDiscountToPercentage();
         decimal nPrice = objParentItem.CalculatePrice();

         if (objParentItem.Quantity > 1)
         {
            nPrice = nPrice / objParentItem.Quantity;;
         }                      
         
         lblPrice.Text = Product.FormatCurrency(nPrice, nCurrencyFormatCode, strCurrencySymbol);
      }

      private void lnkClose_Click(object sender, System.EventArgs e)
      {
         bool bValid = true;

         if (objQuote.IsReadOnly == false)
         {
            UpdatePrice();
            bValid = ValidateConfiguration();
         }

         if (objParentItem.ConfigParentId == Guid.Empty)
         {
            // Return to the quote level
            m_strCloseUrl = "CustomizeQuote.aspx?id={" + guidQuoteId.ToString() + "}&oType=1084&security=852407&tabSet=ConfiguratorArea&CategoryId=" + strRootCategoryId;
         }
         else
         {
            // Return to the parent product
            m_strCloseUrl = "CustomizeItem.aspx?QuoteId=" + objQuote.QuoteId + "&QuoteDetailId=" + objParentItem.ConfigParentId + "&CategoryId=" + strRootCategoryId;
         }

         // If there is a configuration error, we should warn the user before exiting.
         if (bValid)
         {
            Response.Redirect(m_strCloseUrl);
         }
         else
         {
            strValidationProblems = m_mgrResource.GetString("msgValidationProblems");     
            m_bShowValidationWarning = "true";   // Prompt the user with Javascript to make sure they want to continue
         }
      }

      private void btnCustomize_Click(object sender, System.EventArgs e)
      {
         string[] strData = txtCustomizeData.Text.Split(",".ToCharArray());    
         string strCategoryId = strData[0];
         string strProductNumber = strData[1];

         UpdatePrice();
         ValidateConfiguration();
         QuoteDetail objChildItem = objQuote.FindCategoryItem(objParentItem, strCategoryId, strProductNumber);
         
         if (objChildItem != null)
         {
            Response.Redirect("CustomizeItem.aspx?QuoteId=" + objQuote.QuoteId + "&QuoteDetailId=" + objChildItem.QuoteDetailId + "&CategoryId=" + strRootCategoryId);
         }   
      } 

   
   } // end class
}
